package com.bjpowernode.config.handler;

import cn.hutool.json.JSONUtil;
import com.bjpowernode.constant.Constants;
import com.bjpowernode.entity.TUser;
import com.bjpowernode.manager.RedisManager;
import com.bjpowernode.result.R;
import com.bjpowernode.service.UserService;
import com.bjpowernode.utils.JwtUtil;
import com.bjpowernode.utils.ResponseUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 *
 */
@Component
public class AppAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Resource
    private JwtUtil jwtUtil;

    @Resource
    private RedisManager redisManager;

    @Resource
    private UserService userService;

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;


    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.setCharacterEncoding("UTF-8");
        // 登录成功 , 生成jwt
        // 获取到用户的信息
        TUser tUser = (TUser) authentication.getPrincipal();
        // 转换成json
        String userJson = JSONUtil.toJsonStr(tUser);
        // 生成jwt
        String jwt = jwtUtil.generateJwt(userJson);
        // 将jwt写入 redis 数据库进行保存起来
        // 根据前端 是否选择 "记住我" 来设置不同的jwt过期时间
        String rememberMe = request.getParameter("rememberMe");
        boolean isRememberMe = Boolean.parseBoolean(rememberMe);
        if (isRememberMe) {
            // jwt七天后过期
            redisManager.setValue(Constants.REDIS_LOGIN_JWT_KEY + tUser.getId(), jwt , 7 , TimeUnit.DAYS);
        } else {
            // 30分钟后过期
            redisManager.setValue(Constants.REDIS_LOGIN_JWT_KEY + tUser.getId(), jwt , 30 , TimeUnit.MINUTES);
        }

        // 更新一下最近登录时间 , 采用异步更新 , 也就是启动一个新线程去更新登录时间 , 我们此处使用线程池
        threadPoolTaskExecutor.submit(() -> {
            userService.updateLoginTime(tUser.getId());
        });

        // 将jwt返回给前端
        R r = R.OK(jwt);
        ResponseUtil.writeResult(r, response);
    }
}
